%{
#include "grammar.h"
%} 
%union {
	def_ipaddr*        val_ipaddr;
	def_ipaddr_area*   val_ipaddr_area;
	def_macaddr *      val_macaddr;
	def_macaddr_area*  val_macaddr_area;	
	def_number         val_number;
	def_number_area*   val_number_area;	
	def_hex*           val_hex;
	def_string         val_string;
	def_node*          val_node;
	char*              text;
	}

%token <val_ipaddr>       IPADDR
%token <val_ipaddr_area>  IPADDR_AREA
%token <val_macaddr>      MACADDR
%token <val_macaddr_area> MACADDR_AREA
%token <val_number>       NUMBER
%token <val_number_area>  NUMBER_AREA
%token <val_hex>          HEX
%token <val_string>       STRING

%token END
%token AND OR NOT
%token SRC DES PORT DATA AREA
%token MAC IP PACKET TCP UDP ETHER

%type <val_node>         ipaddr
%type <val_node>		 ipaddr_area
%type <val_node>         macaddr
%type <val_node>         macaddr_area
%type <val_node>         number
%type <val_node>     	 number_area
%type <val_node>         hex
%type <val_node>         string

%type <val_node>         tern expr exprs
%%
program:
	exprs END
	{
		grammar_create_node(enum_node_type_parse, enum_parse_type_program, 1, $1);			
	}
	;|
	END
	{
		grammar_create_node(enum_node_type_parse, enum_parse_type_end, 0);		
	}
	;


exprs:
	expr
	{
		$$ = grammar_create_node(enum_node_type_parse, enum_parse_type_expr, 1, $1);
	}
	;|
	exprs AND expr
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_op_and, 2, $1, $3);
	}
	;|
	exprs OR expr
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_op_or, 2, $1, $3);
	}
	;

expr:
	tern
	{
		$$ = grammar_create_node(enum_node_type_parse, enum_parse_type_tern, 1, $1);		
	}
	;|
	NOT tern
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_op_not, 1, $2);
	}
	;
		
tern:
	'(' exprs ')'
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_op_bracket, 1, $2);
	}
	;|	
	PACKET '.' DATA '[' number ']' '=' number
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_packet_data_byte, 2, $5, $8);
	}
	;|
	PACKET '.' DATA '[' number_area ']' '=' hex
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_packet_data_area, 2, $5, $8);
	}
	;|
	IP '.' SRC '=' ipaddr 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_ip_src, 1, $5);
	}
	;|
	IP '.' DES '=' ipaddr 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_ip_des, 1, $5);
	}
	;|
	MAC '.' SRC '=' macaddr 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_mac_src, 1, $5);
	}
	;|
	MAC '.' DES '=' macaddr 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_mac_des, 1, $5);
	}
	;|	
	TCP '.' PORT '.' SRC '=' number 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_tcp_port_src, 1, $7);
	}
	;|
	TCP '.' PORT '.' DES '=' number 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_tcp_port_des, 1, $7);
	}
	;|
	UDP '.' PORT '.' SRC '=' number 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_udp_port_src, 1, $7);
	}
	;|
	UDP '.' PORT '.' DES '=' number 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_udp_port_des, 1, $7);
	}
	;|
	IP '.' SRC '=' ipaddr_area 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_ip_src, 1, $5);
	}
	;|
	IP '.' DES '=' ipaddr_area 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_ip_des, 1, $5);
	}
	;|
	MAC '.' SRC '=' macaddr_area 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_mac_src, 1, $5);
	}
	;|
	MAC '.' DES '=' macaddr_area 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_mac_des, 1, $5);
	}
	;|	
	TCP '.' PORT '.' SRC '=' number_area 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_tcp_port_src, 1, $7);
	}
	;|
	TCP '.' PORT '.' DES '=' number_area 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_tcp_port_des, 1, $7);
	}
	;|
	UDP '.' PORT '.' SRC '=' number_area 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_udp_port_src, 1, $7);
	}
	;|
	UDP '.' PORT '.' DES '=' number_area 
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_udp_port_des, 1, $7);
	}
	;|
	TCP '.' DATA '[' number ']' '=' number
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_tcp_data_byte, 2, $5, $8);
	}
	;|
	TCP '.' DATA '[' number_area ']' '=' hex
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_tcp_data_area, 2, $5, $8);
	}
	;|
	UDP '.' DATA '[' number ']' '=' number
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_udp_data_byte, 2, $5, $8);
	}
	;|
	UDP '.' DATA '[' number_area ']' '=' hex
	{
		$$ = grammar_create_node(enum_node_type_operation, enum_operation_type_udp_data_area, 2, $5, $8);
	}
	;
	
ipaddr:
	IPADDR
	{
		$$ = grammar_create_node(enum_node_type_value, enum_value_type_ipaddr, 1, $1);
	}
ipaddr_area:
	IPADDR_AREA
	{
		$$ = grammar_create_node(enum_node_type_value, enum_value_type_ipaddr_area, 1, $1);
	}
macaddr:
	MACADDR
	{
		$$ = grammar_create_node(enum_node_type_value, enum_value_type_macaddr, 1, $1);
	}
macaddr_area:
	MACADDR_AREA
	{
		$$ = grammar_create_node(enum_node_type_value, enum_value_type_macaddr_area, 1, $1);
	}
number:
	NUMBER
	{
		$$ = grammar_create_node(enum_node_type_value, enum_value_type_number, 1, $1);
	}
number_area:
	NUMBER_AREA
	{
		$$ = grammar_create_node(enum_node_type_value, enum_value_type_number_area, 1, $1);
	}
hex:
	HEX
	{
		$$ = grammar_create_node(enum_node_type_value, enum_value_type_hex, 1, $1);
	}
string:
	STRING
	{
		$$ = grammar_create_node(enum_node_type_value, enum_value_type_string, 1, $1);
	}
		
%%

